package com.fcmeditech.AsianSexyGirls.File;



import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

public class BitmapManager {
	

	private final  Map<String, SoftReference<Bitmap>> cache;//--->soft cache to store bitmap  
    private final ExecutorService pool;  
    private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());  
    //--------------Constructor------------------------------
    public BitmapManager() {  
        cache = new HashMap<String, SoftReference<Bitmap>>();  //--->create a cache 
       // pool = Executors.newFixedThreadPool(5);//--->create 5 thread  
    pool=Executors.newFixedThreadPool(2);
    }  
//-------------Set Default Image-------------------------- 
    public void setPlaceholder(Bitmap bmp) {  
    }  
  //------------getBitmapFromCache-------------------------
    public Bitmap getBitmapFromCache(String url) {  
        if (cache.containsKey(url)) {  
            return cache.get(url).get();  
        }  
  
        return null;  
    }  
 //---------------------Run Thread and Update UI via Handler----------
    public void queueJob(final String url, final ImageView imageView,  
            final int width, final int height,final int position) {  
        /* Create handler in UI thread. */  
      /**
       * Handler method() is used to recieved message from a Handler in Thread
       */
    	 
    	final Handler handler = new Handler() {  
            @Override  
            public void handleMessage(Message msg) {  
            	String tag = imageViews.get(imageView);//--->GET url OF imageView in Map<>  
                if (tag != null && tag.equals(url))
                   {  
                    if (msg.obj != null) {  
                        imageView.setImageBitmap((Bitmap)msg.obj); //--->Receive msg.obj from Handler in pool.submit(Runable ) belows.
                        Log.d(String.valueOf(position),"Message is recieved!Image Displayed!");
                    } else {  
                        Log.d(String.valueOf(position), "fail " + url);  
                    }  
                }  
            }  
        };  
        //---Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return null upon successful completion.
  
        pool.submit(new Runnable() {  
            @Override  
            public void run() {  
            	Bitmap bmp=null;
				bmp = downloadBitmap2(url);
				bmp=rotate90(bmp);
				Log.d(String.valueOf(position),"Item is downloaded from URL: " + url); 
				//-----------Create a message to send to HandlerMessage------------------------------
                Message message = Message.obtain(); //--->create a new message 
                message.obj = bmp;  //--->set object of message =bmp;
                handler.sendMessage(message);  //--->Pushes a message onto the end of the message queue after all pending messages before the current time.
                //It will be received in handleMessage, in the thread attached to this handler.

            }  
        }); 
        
    }  
  //--------------------Load Bitmap from Cache-------------------------------------------------------------------------//
    public void loadBitmap(final String url, final ImageView imageView,final int width, final int height,int position) {  
          //--->put imageView and Its URL to MAP<>
    	imageViews.put(imageView, url);//--->
    	//Log.d("Hard Cache Size",String.valueOf(imageViews.size()));
    	
        Bitmap bitmap = getBitmapFromCache(url);  //--->getBitMap from Cache
              
        if (bitmap != null) {  
        	 // check in UI thread, so no concurrency issues 
        	bitmap=rotate90(bitmap);
        	imageView.setImageBitmap(bitmap);
        	Log.d(String.valueOf(position), "Item loaded from cache:Image is set! " + url);
        } else {  
           queueJob(url, imageView, width, height,position);//---> If there is no Bitmap in Cache--->download it from URL
        }
    }  
  
    
  //---------------------------Download Bitmap from URL-----------------------------------//
      public  Bitmap downloadBitmap2(String url) {
        Bitmap bm=null;
        // AndroidHttpClient is not allowed to be used from the main thread
        final HttpClient client = new DefaultHttpClient();
        final HttpGet getRequest = new HttpGet(url);

        try {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                Log.w("ImageDownloader", "Error " + statusCode +
                        " while retrieving bitmap from " + url);
                return null;
            }

            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    inputStream = entity.getContent();
                    // return BitmapFactory.decodeStream(inputStream);
                    // Bug on slow connections, fixed in future release.
                    bm=BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
                    cache.put(url, new SoftReference<Bitmap>(bm));
                 return bm;
                
                 } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        } catch (IOException e) {
            getRequest.abort();
            Log.w("LOG_TAG", "I/O error while retrieving bitmap from " + url, e);
        } catch (IllegalStateException e) {
            getRequest.abort();
            Log.w("LOG_TAG", "Incorrect URL: " + url);
        } catch (Exception e) {
            getRequest.abort();
            Log.w("LOG_TAG", "Error while retrieving bitmap from " + url, e);
        } finally {

        }
        return null;
    }

//-------------------Check the InputStream----Should set FlushInputStream below the decode bitmap method-------------------//
    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }
//---------------Clear Cache Memory-------------------
    public void clearImageViewsMap()
    {
    	imageViews.clear();
    	cache.clear();
    }
//-----------Rotate Image  Automatically-----------
    private Bitmap rotate90(Bitmap img)
    {
    	int height=img.getHeight();
        int width=img.getWidth();
        if(height<width){
        	Matrix mat=new Matrix();
        	mat.preRotate(90);
        	Log.d("Rotate","Pic is rotated ");
        	return Bitmap.createBitmap(img, 0, 0, width, height, mat, true);
        } else return img;
    }

}